using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;

namespace AppScan.Extensions.EventLogger
{
    public partial class Config : Form
    {

        private EventLogger logger;

        public Config(EventLogger logger)
        {
            this.logger = logger;
            InitializeComponent();
        }

        private void Config_Load(object sender, EventArgs e)
        {
            checkedListBoxEvents.Items.Clear();

            foreach (ReflectionEventHandler handler in logger.EventHandlers.Values)
            {
                checkedListBoxEvents.Items.Add(handler, handler.Enabled);
            }

            if (logger.Enabled)
            {
                buttonEnable.Text = "Disable";
                this.Text = "EventLogger Configuration (Enabled)";
            }
            else
            {
                buttonEnable.Text = "Enable";
                this.Text = "EventLogger Configuration (Disabled)";
            }

            try
            {
                numericUpDownLogCacheSize.Value = logger.LogCacheSize;
            }
            catch (ArgumentOutOfRangeException)
            {
            }

            try
            {
                numericUpDownMaxLogSize.Value = logger.MaxLogSize >> 20;
            }
            catch (ArgumentOutOfRangeException)
            {
            }

            textBoxLogFileName.Text = logger.LogFileName;


        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < checkedListBoxEvents.Items.Count; ++i)
            {
                logger.EventHandlers[checkedListBoxEvents.Items[i].ToString()].Enabled = checkedListBoxEvents.GetItemChecked(i);
            }

            logger.LogFileName = textBoxLogFileName.Text;
            logger.LogCacheSize = (int)numericUpDownLogCacheSize.Value;
            logger.MaxLogSize = (int)numericUpDownMaxLogSize.Value * (1<<20);

            logger.ExportConfig();
        }

        private void buttonLogFileName_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                if (showSaveDialog(sfd) == DialogResult.OK)
                {
                    textBoxLogFileName.Text = sfd.FileName;
                }
            }
        }

        private void buttonEnable_Click(object sender, EventArgs e)
        {
            if (logger.Enabled)
            {
                if (MessageBox.Show("Are you sure you want to disable EventLogger?", "Disable EventLogger", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    logger.Enabled = false;
                    buttonEnable.Text = "Enable";
                    this.Text = "EventLogger Configuration (Disabled)";
                }
            }
            else
            {
                logger.Enabled = true;
                buttonEnable.Text = "Disable";
                this.Text = "EventLogger Configuration (Enabled)";
            }
        }


        private DialogResult lastDialogResult;
        private object sfdsync = new object();
        private object sfdsync2 = new object();

        private DialogResult showSaveDialog(SaveFileDialog sfd)
        {
            // Make sure the dialog is only shown once at a time
            lock (sfdsync)
            {
                lock (sfdsync2)
                {
                    Thread t = new Thread(new ParameterizedThreadStart(showSaveDialogThread));
                    t.SetApartmentState(ApartmentState.STA);
                    t.Start(sfd);
                    Monitor.Wait(sfdsync2);
                }
            }
            return lastDialogResult;
        }

        private void showSaveDialogThread(object parameter)
        {
            lock (sfdsync2)
            {
                try
                {
                    if (parameter is SaveFileDialog)
                    {
                        lastDialogResult = (parameter as SaveFileDialog).ShowDialog();
                    }
                }
                finally
                {
                    Monitor.PulseAll(sfdsync2);
                }
            }
        }

    }
}